package com.centerm.bluetooth.dy;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.text.TextUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.centerm.bluetooth.common.controller.PBOCController;
import com.centerm.bluetooth.common.controller.PinController;
import com.centerm.bluetooth.common.controller.ScreenController;
import com.centerm.bluetooth.common.controller.TerminalController;
import com.centerm.bluetooth.common.controller.TerminalSafeController;
import com.centerm.bluetooth.common.controller.TradeController;
import com.centerm.bluetooth.common.listener.IPBOCListener;
import com.centerm.bluetooth.common.listener.IPinListener;
import com.centerm.bluetooth.common.listener.IScreenListener;
import com.centerm.bluetooth.common.listener.ITerminalListener;
import com.centerm.bluetooth.common.listener.ITerminalSafeListener;
import com.centerm.bluetooth.common.listener.ITradeListener;
import com.centerm.bluetooth.common.model.CardInfo;
import com.centerm.bluetooth.common.model.Version;
import com.centerm.bluetooth.core.controller.BluetoothController;
import com.centerm.bluetooth.core.controller.constants.BluetoothState;
import com.centerm.bluetooth.core.listener.IBluetoothFoundListener;
import com.centerm.bluetooth.core.listener.IBluetoothStateListener;
import com.centerm.bluetooth.dy.listener.SwiperListener;
import com.centerm.bluetooth.dy.model.Device;
import com.centerm.bluetooth.dy.model.SalesSlip;
import com.centerm.bluetooth.dy.model.TransType;
import com.centerm.bluetooth.ibridge.BluetoothIBridgeDevice;
import com.centerm.bluetooth.ibridge.constants.ChannelConfig;
import com.centerm.util.HexUtil;
import com.centerm.util.Logger;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by linwenhui on 2017/4/28.
 */

public class SwiperController {
    private static SwiperController instance;
    private Context context;
    private SwiperListener swiperListener;
    private BluetoothController bluetoothController;
    private TerminalController terminalController;
    private TradeController tradeController;
    private PBOCController pbocController;
    private PinController pinController;
    private TerminalSafeController terminalSafeController;
    private ScreenController screenController;
    private POSImp posImp;
    private BluetoothImp bluetoothImp;

    private String orderId;//订单号
    private String transLogo;//流水号
    private Device device;//设备信息
    private boolean openCardReaderResult;
    private boolean resetResult;
    private int moneyInt;
    private int timeout;
    private List<BluetoothDevice> seachDevices;
    private Timer bluetoothScanTimer;
    private static Handler mainHandler = new Handler(Looper.getMainLooper());
    private BluetoothIBridgeDevice curConnectedDevice;

    private SwiperController(Context context) {
        this.context = context;
        ChannelConfig.getInstance().setChannel(ChannelConfig.CENTERM);
        Logger.setDEBUG(false, false);
        bluetoothImp = new BluetoothImp();
        bluetoothController = BluetoothController.getInstance(context);
        bluetoothController.setBluetoothFoundListener(bluetoothImp);
        bluetoothController.setBluetoothStateListener(bluetoothImp);
        posImp = new POSImp();
        terminalController = new TerminalController(context);
        terminalController.setListener(posImp);
        tradeController = new TradeController(context);
        tradeController.setListener(posImp);
        pbocController = new PBOCController(context);
        pbocController.setListener(posImp);
        pinController = new PinController(context);
        pinController.setListener(posImp);
        terminalSafeController = new TerminalSafeController(context);
        terminalSafeController.setListener(posImp);
        screenController = new ScreenController(context);
        screenController.setListener(posImp);

    }

    /**
     * 获取蓝牙刷卡器操作类
     *
     * @param context
     * @return
     */
    public static SwiperController getControllerInstance(@NonNull Context context) {
        if (instance == null) {
            synchronized (SwiperController.class) {
                if (instance == null) {
                    instance = new SwiperController(context);
                }
            }
        }
        return instance;
    }

    /**
     * 设置SwiperController的监听器（替换初始化时候的监听器，用于在不同页面重新设置监听器）
     *
     * @param swiperListener
     */
    public void setSwiperListener(SwiperListener swiperListener) {
        this.swiperListener = swiperListener;
    }

    /**
     * 开始搜索设备,s秒后返回设备列表
     *
     * @param timeout
     */
    public void startScanDevice(int timeout) {
        stopSearch();
        if (seachDevices == null) {
            seachDevices = new ArrayList<>();
        } else {
            seachDevices.clear();
        }
        bluetoothScanTimer = new Timer();
        bluetoothScanTimer.schedule(new BlueSeachTimeout(), timeout * 1000);
        bluetoothController.startDiscovery();
    }

    /**
     * 用户可以手动停止搜索设备
     */
    public void stopSearch() {
        if (bluetoothScanTimer != null)
            bluetoothScanTimer.cancel();
        bluetoothController.stopDiscovery();
        if (seachDevices == null) {
            seachDevices = new ArrayList<>();
        } else {
            seachDevices.clear();
        }
    }

    /**
     * 连接设备
     *
     * @param device
     */
    public void conectDevice(BluetoothDevice device) {
        curConnectedDevice = BluetoothIBridgeDevice.createBluetoothIBridgeDevice(device.getAddress());
        bluetoothController.connect(curConnectedDevice);
    }

    /**
     * 获取 蓝牙刷卡器设备信息 例如设备号  psam卡号 版本号等
     *
     * @return
     */
    public Device getDeviceInfo() {
        device = null;
        boolean res = false;
        try {
            res = terminalController.getVersion();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (res) {
            int timeout = 60000;
            while (timeout > 0 && device == null) {
                timeout -= 100;
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        return device;
    }

    /**
     * 连接设备，新的设备第一次使用 (用于设备没有终端号手动写入，可以不调用)
     *
     * @param terminalId  终端码
     * @param merchant    商户标识
     * @param merhantName 商户名
     * @return
     */
    public int finishInitDevice(String terminalId, String merchant, String merhantName) {
        return -1;
    }

    /**
     * 设置主秘钥 (测试时使用，可以不调用)
     *
     * @param mastkey 32位主秘钥信息
     * @return -1：IO操作失败；-2：输入参数无效；-3：无效的密钥组类型；-4：无效的密钥组ID；-5：无效的密钥长度；-6：未知错误
     */
    public int reSetMasterkey(String mastkey) {
        return -1;
    }

    /**
     * @param orderId   订单号 16位字符
     * @param transLogo 流水号 6位字符
     * @param cash      交易金额（可以用double类型的以元为单位，或者long类型以分为单位）
     * @param transType 交易类型 (自定义，例如消费、查询等)
     * @param timeout   刷卡等待的超时时间(单位秒)(如果超时之后，在onYJEMVError中根据errorCode处理)
     * @return true 表示开始刷卡成功, false 表示失败
     */
    public synchronized boolean startPOS(String orderId, String transLogo, double cash, TransType transType, int timeout) {
        this.transLogo = transLogo;
        this.orderId = orderId;
        posImp.setInputPin(true);
        posImp.setMode(1);
        this.timeout = timeout;
        if (transType == TransType.TransType_Payment) {
            Double cashDouble = new Double(cash * 100);
            moneyInt = cashDouble.intValue();
        } else {
            moneyInt = -1;
        }
        openCardReaderResult = false;
        boolean res = false;
        try {
            res = tradeController.openCardReader(HexUtil.hexStr2Bytes(transLogo), timeout, moneyInt);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (res) {
            int time = 60000;
            while (time > 0 && !openCardReaderResult) {
                time -= 100;
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        return openCardReaderResult;
    }

    /**
     * 取消刷卡
     */
    public void cancelWaitForCard() {
        resetResult = false;
        try {
            boolean res = terminalController.reset();
            if (res) {
                int time = 60000;
                while (time > 0 && !resetResult) {
                    time -= 100;
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 提交交易完成后的信息
     *
     * @param succeed 交易结果，true 为交易成功
     * @param result  交易结果描述
     * @param filed55 ic卡交易后更新信息
     */
    public void sendPayResult(boolean succeed, String result, byte[] filed55) {

    }

    /**
     * 获取开发文档版本号 （可选，可不调用）
     *
     * @return
     */
    public String getApiVersion() {
        return "1";
    }

    /**
     * @param x    横坐标
     * @param y    纵坐标
     * @param data 显示信息
     */
    public void LcdString(@IntRange(from = 0, to = 0x14) int x, @IntRange(from = 0, to = 2) int y, String data) {
        String line2 = null, line3 = null, line4 = null;
        switch (y) {
            case 0:
                line2 = data;
                break;
            case 1:
                line3 = data;
                break;
            case 2:
                line4 = data;
                break;
        }
        try {
            screenController.terminalDisplay(x, line2, x, line3, x, line4, 3);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 释放sdk资源
     */
    public void releaseDevice() {
        cancelWaitForCard();
        if (curConnectedDevice != null)
            bluetoothController.disconnect(curConnectedDevice);
    }

    /**
     * 获取卡号明文
     */
    public void startGetCardNo() {
        posImp.setInputPin(false);
        posImp.setMode(2);
        this.timeout = 60;
        moneyInt = 0;
        openCardReaderResult = false;
        try {
            tradeController.openCardReader(HexUtil.hexStr2Bytes("000001"), timeout, moneyInt);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 打印签购单
     *
     * @param salesSlip
     * @param data
     * @return
     */
    public boolean printSalesSlip(SalesSlip salesSlip, HashMap data) {
        return false;
    }

    private class BlueSeachTimeout extends TimerTask {

        @Override
        public void run() {
            bluetoothController.stopDiscovery();
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (swiperListener != null)
                        swiperListener.onFindDevices(seachDevices);
                }
            });
        }
    }

    private class BluetoothImp implements IBluetoothStateListener, IBluetoothFoundListener {

        @Override
        public void onBluetoothStateChange(BluetoothState state) {

            if (state == BluetoothState.CONNECTED) {
                if (swiperListener != null) {
                    swiperListener.onDeviceConnected();
                }
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        getDeviceInfo();
                    }
                }).start();
            } else if (state == BluetoothState.DISCONNECTED) {
                if (swiperListener != null) {
                    swiperListener.onDeviceDisConnected();
                }
            } else if (state == BluetoothState.CONNECT_LOST) {
                if (swiperListener != null) {
                    swiperListener.onDeviceConnectTimeout();
                }
            }

        }

        @Override
        public void onDeviceFound(BluetoothIBridgeDevice device) {
            if (seachDevices == null)
                seachDevices = new ArrayList<>();
            seachDevices.add(BluetoothAdapter.getDefaultAdapter().getRemoteDevice(device.getDeviceAddress()));
        }

        @Override
        public void onDiscoveryFinished() {

        }
    }

    private class POSImp implements ITerminalListener, ITradeListener, IPBOCListener, IPinListener, ITerminalSafeListener, IScreenListener {

        private boolean inputPin;
        private int mode;// 1：消费，2：读卡
        private int cardType;//0：磁条卡，1：IC卡，2：非接
        private Device localDevice;
        private CardInfo cardInfo;

        public POSImp() {
            cardInfo = new CardInfo();
        }

        public void setInputPin(boolean inputPin) {
            this.inputPin = inputPin;
        }

        public void setMode(int mode) {
            this.mode = mode;
        }

        @Override
        public void onError(final int code, final String msg) {
            Logger.i(" code = " + code + " , msg = " + msg);
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (swiperListener != null)
                        swiperListener.onYJEMVError(code+8, msg);
                }
            });
        }

        @Override
        public void onTimeout() {
            Logger.i(" == onTimeout == ");
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (swiperListener != null)
                        swiperListener.onYJEMVError(2, "接收超时");
                }
            });
        }

        @Override
        public void onCancelSwipeCard() {
            Logger.i(" == onCancelSwipeCard == ");
            if (swiperListener != null)
                swiperListener.onSwipeCardCancel();
        }

        @Override
        public void onWaitForSwipeCard() {
            openCardReaderResult = true;
            Logger.i(" == onWaitForSwipeCard == ");
        }

        @Override
        public void onSwiperSuc() {
            cardType = 0;
            Logger.i(" == onSwiperSuc == ");
            try {
                tradeController.getTradeData();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onSwiperFalse() {
            Logger.i(" == onSwiperFalse == ");
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (swiperListener != null)
                        swiperListener.onYJEMVError(4, "刷卡失败");
                }
            });
        }

        @Override
        public void onSwiperTimeout() {
            Logger.i(" == onSwiperTimeout == ");
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (swiperListener != null)
                        swiperListener.onYJEMVError(3, "刷卡超时");
                }
            });
        }

        @Override
        public void onICInsert() {
            cardType = 1;
            String moneyString;
            if (moneyInt >= 0) {
                moneyString = String.format("%012d", moneyInt);
            } else {
                moneyString = String.format("%012d", 0);
            }
            try {
                pbocController.startPBOC(moneyString);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onNFInsert() {
            cardType = 2;
            String moneyString;
            if (moneyInt >= 0) {
                moneyString = String.format("%012d", moneyInt);
            } else {
                moneyString = String.format("%012d", 0);
            }
            try {
                pbocController.startQPBOC(moneyString);
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void onCardType(int cardType) {
            Logger.i(" == onCardType == " + cardType);
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (swiperListener != null)
                        swiperListener.onYJEMVError(0x04, "刷卡失败");
                }
            });
        }

        @Override
        public void onSwiperCompelete(String result) {
            Logger.i(" == onSwiperCompelete == " + result);
            final JSONObject params = JSON.parseObject(result);
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (mode == 2 && swiperListener != null) {
                        swiperListener.onBackCardNo(params.getString("pan"));
                    }
                }
            });

            cardInfo.setTradeTwo(params.getString("tradeTwo"));
            cardInfo.setTradeThree(params.getString("tradeThree"));
            cardInfo.setTrade(params.getString("tradeTwo") + params.getString("tradeThree"));
            cardInfo.setTradeRandom(params.getString("random"));
            cardInfo.setPan(params.getString("pan"));
            cardInfo.setPanRandom(params.getString("random"));
            cardInfo.setSecurePan(null);
            cardInfo.setCardSerial(null);
            cardInfo.setExpireDate(params.getString("expireDate"));
            String moneyString;
            if (moneyInt >= 0) {
                moneyString = String.format("%012d", moneyInt);
            } else {
                moneyString = "FFFFFFFFFFFF";
            }
            if (inputPin) {
                try {
                    pinController.startInputPin(timeout, moneyString);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void onGetVersion(Version version) {
            Logger.i(" == onGetVersion ==");
            Device tmp = new Device();
            tmp.setTerminalId(version.getSn());
            tmp.setPsamNo(version.getKsn());
            tmp.setUid(version.getTerminalid());
            tmp.setSoftVersion(version.getSoftVer());
            tmp.setHardVersion(version.getHardVer());
            tmp.setBatteryLevel(version.getBatteryLevel() + "");
            tmp.setBatteryPercentage(version.getBatteryPercentage() + "");
            tmp.setScreenLight(version.getScreenLight() + "");
            localDevice = tmp.clone();
            device = tmp.clone();
        }

        @Override
        public void onReset() {
            Logger.i(" == onReset ==");
            resetResult = true;
        }

        @Override
        public void onGetPSAMAndTerminal(String s) {

        }

        @Override
        public void onWaitForPBOCResult() {
            Logger.i(" == onWaitForPBOCResult == ");
        }

        @Override
        public void onPBOCResult(String result) {
            Logger.i(" == onPBOCResult == " + result);
            String moneyString;
            if (moneyInt >= 0) {
                moneyString = String.format("%012d", moneyInt);
            } else {
                moneyString = "FFFFFFFFFFFF";
            }

            final JSONObject params = JSON.parseObject(result);
            if (mode == 2 && swiperListener != null) {
                mainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        swiperListener.onBackCardNo(params.getString("pan"));
                    }
                });

            }
            cardInfo.setTrade(params.getString("icdata"));
            cardInfo.setTradeRandom(params.getString("random"));
            cardInfo.setPan(params.getString("pan"));
            cardInfo.setPanRandom(params.getString("random"));
            cardInfo.setSecurePan(params.getString("securePan"));
            cardInfo.setCardSerial(params.getString("cardSerial"));
            cardInfo.setExpireDate(params.getString("expireDate"));

            if (inputPin) {
                try {
                    pinController.startInputPin(timeout, moneyString);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                try {
                    pbocController.endPBOC(0);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void onEndPBOC() {
            try {
                terminalController.reset();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onPBOCError() {
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (swiperListener != null) {
                        swiperListener.onYJEMVError(0x07, "读卡失败");
                    }
                }
            });
        }

        @Override
        public void onGetInputPin(byte[] pinblock, byte[] random) {
            cardInfo.setPinBlock(HexUtil.byte2HexStr(pinblock));
            cardInfo.setPinBlockRandom(HexUtil.byte2HexStr(random));
            Logger.i(" == onGetInputPin ==");
            Logger.i(pinblock, Logger.TYPE.CODE16);
            StringBuffer macBuffer = new StringBuffer();
            //IC卡数据密文/二三磁道密文
            macBuffer.append(cardInfo.getTrade());
            //IC卡数据加密随机数/磁道加密随机数
            macBuffer.append(cardInfo.getTradeRandom().substring(0, 8));
            //PIN密文,PIN加密随机数
            macBuffer.append(cardInfo.getPinBlock());
            macBuffer.append(cardInfo.getPinBlockRandom().substring(0, 8));
            //终端号及psam号
            macBuffer.append(localDevice.getTerminalId());
            macBuffer.append(localDevice.getPsamNo());
            //订单号
            macBuffer.append(HexUtil.toASCII(orderId));
            Logger.i(" mac == " + macBuffer.toString());
            try {
                terminalSafeController.calMac(HexUtil.hexStr2Bytes(transLogo), HexUtil.hexStr2Bytes(macBuffer.toString()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onInputPinEmpty() {
            Logger.i(" == onInputPinEmpty == ");
            cardInfo.setPinBlock(null);
            StringBuffer macBuffer = new StringBuffer();
            //IC卡数据密文/二三磁道密文
            macBuffer.append(cardInfo.getTrade());
            //IC卡数据加密随机数/磁道加密随机数
            macBuffer.append(cardInfo.getTradeRandom().substring(0, 8));
            //终端号及psam号
            macBuffer.append(localDevice.getTerminalId());
            macBuffer.append(localDevice.getPsamNo());
            //订单号
            macBuffer.append(HexUtil.toASCII(orderId));
            Logger.i(" mac == " + macBuffer.toString());
            try {
                terminalSafeController.calMac(HexUtil.hexStr2Bytes(transLogo), HexUtil.hexStr2Bytes(macBuffer.toString()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onWaitForInputPin() {
            Logger.i(" == onWaitForInputPin ==");
        }

        @Override
        public void onInputPinCancel() {
            Logger.i(" == onInputPinCancel ==");
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (swiperListener != null)
                        swiperListener.onYJEMVError(5, "取消输密");
                }
            });
        }

        @Override
        public void onInputPinTimeout() {
            Logger.i(" == onInputPinTimeout ==");
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (swiperListener != null)
                        swiperListener.onYJEMVError(6, "输密超时");
                }
            });
        }

        @Override
        public void onGetMac(byte[] mac) {
            Logger.i(" == onGetMac == ");
            Logger.i(mac, Logger.TYPE.CODE16);
            Logger.i(cardInfo);
            final StringBuffer allDatas = new StringBuffer();
            StringBuffer bodyBuffer = new StringBuffer();
            if (cardType == 0) {
                allDatas.append("FB00");
                //一磁道长度
                bodyBuffer.append("00");
                //二磁道长度
                bodyBuffer.append(String.format("%02x", cardInfo.getTradeTwo().length() / 2));
                //三磁道长度
                bodyBuffer.append(String.format("%02x", cardInfo.getTradeThree().length() / 2));
                //磁道随机数长度
                bodyBuffer.append("04");
                //终端号及psam号长度
                bodyBuffer.append(String.format("%02x", (localDevice.getTerminalId().length() + localDevice.getPsamNo().length()) / 2));
                //卡号长度
                bodyBuffer.append(String.format("%02x", cardInfo.getPan().length()));
                //二磁道加密信息,三磁道加密信息
                bodyBuffer.append(cardInfo.getTrade());
                //磁道随机数
                bodyBuffer.append(cardInfo.getTradeRandom().substring(0, 8));
                //终端号及psam号
                bodyBuffer.append(localDevice.getTerminalId());
                bodyBuffer.append(localDevice.getPsamNo());
                //卡号明文
                bodyBuffer.append(HexUtil.toASCII(cardInfo.getPan()));
                //PIN密文长度及PIN随机数长度
                if (TextUtils.isEmpty(cardInfo.getPinBlock())) {
                    bodyBuffer.append("00");
                } else {
                    //PIN密文长度及PIN随机数长度
                    bodyBuffer.append(String.format("%02x", (cardInfo.getPinBlock().length() / 2 + 4)));
                    //PIN密文及PIN随机数
                    bodyBuffer.append(cardInfo.getPinBlock());
                    bodyBuffer.append(cardInfo.getPinBlockRandom().substring(0, 8));
                }
            } else {
                if (cardType == 1)
                    allDatas.append("FA00");
                else
                    allDatas.append("DA00");
                //IC卡数据密文长度
                bodyBuffer.append(String.format("%04x", cardInfo.getTrade().length() / 2));
                //IC卡数据加密随机数长度
                bodyBuffer.append("04");
                //卡号加密随机数长度
                bodyBuffer.append("04");
                //终端号及psam号长度
                bodyBuffer.append(String.format("%02x", (localDevice.getTerminalId().length() + localDevice.getPsamNo().length()) / 2));
                //卡号密文长度
                bodyBuffer.append(String.format("%02x", cardInfo.getSecurePan().length() / 2));
                //IC卡密文信息
                bodyBuffer.append(cardInfo.getTrade());
                //IC卡数据加密随机数
                bodyBuffer.append(cardInfo.getTradeRandom().substring(0, 8));
                //终端号及psam号
                bodyBuffer.append(localDevice.getTerminalId());
                bodyBuffer.append(localDevice.getPsamNo());
                //卡号密文数据
                bodyBuffer.append(cardInfo.getSecurePan());
                //卡号加密随机数
                bodyBuffer.append(cardInfo.getPanRandom().substring(0, 8));
                //卡片序列号
                bodyBuffer.append(HexUtil.toASCII(cardInfo.getCardSerial()));
                if (TextUtils.isEmpty(cardInfo.getPinBlock())) {
                    bodyBuffer.append("00");
                } else {
                    //PIN密文长度及PIN随机数长度
                    bodyBuffer.append(String.format("%02x", (cardInfo.getPinBlock().length() / 2 + 4)));
                    //PIN密文及PIN随机数
                    bodyBuffer.append(cardInfo.getPinBlock());
                    bodyBuffer.append(cardInfo.getPinBlockRandom().substring(0, 8));
                }
            }
            //卡有效期
            bodyBuffer.append(HexUtil.toASCII(cardInfo.getExpireDate()));
            //MAC值及MAC随机数
            bodyBuffer.append(HexUtil.byte2HexStr(mac));

            String allLen = HexUtil.byte2HexStr(HexUtil.toHexLen(bodyBuffer.length() / 2));
            Logger.i(" allLen == " + allLen);
            allDatas.append(allLen);
            allDatas.append(bodyBuffer);
            Logger.i(allDatas.toString());

            if (swiperListener != null) {
                mainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        swiperListener.onGetTrackData(cardInfo.getPan(), allDatas.toString().toUpperCase());
                    }
                });

            }

            if (cardType != 0) {
                try {
                    pbocController.endPBOC(0);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void onScreenDisplay() {
            Logger.i(" == onScreenDisplay == ");
        }
    }

}
